using System.Drawing;
using System.Windows.Forms;
using ComponentFactory.Krypton.Toolkit;
using Nuwanda.TfsSpotlight.Shell.Expressions;
using Nuwanda.TfsSpotlight.Shell.Proxies.Interfaces;
using Nuwanda.TfsSpotlight.Shell.Services;
using ObjectFactory=StructureMap.ObjectFactory;

namespace Nuwanda.TfsSpotlight.Shell.Proxies
{
    public class SideBarProxy : ISideBar
    {
        private readonly KryptonHeaderGroup _headerGroup;
        private readonly KryptonSplitContainer _splitContainer;
        private readonly IToolStrip _toolStrip;
        private readonly string _location;
        private int _width;
        private readonly ControlInvoker _headerInvoker;

        public int Width
        {
            get
            {
                return this._headerInvoker.RunAndReturnInControlsThread(
                    () => this.Collapsed ? _width : this._headerGroup.Width);
            }
            set
            {
                this._headerInvoker.RunInControlsThread(
                    () => this._width = value);
            }
        }

        public Image Icon
        {
            get
            {
                return this._headerInvoker.RunAndReturnInControlsThread(
                    () => this._headerGroup.ValuesPrimary.Image);
            }
            set 
            {
                this._headerInvoker.RunInControlsThread(
                    () => this._headerGroup.ValuesPrimary.Image = value);
            }
        }

        public SideBarProxy(KryptonHeaderGroup headerGroup, KryptonSplitContainer splitContainer, IToolStrip toolStrip, string location)
        {
            this._headerGroup = headerGroup;
            this._headerInvoker = new ControlInvoker(headerGroup);
            this._splitContainer = splitContainer;
            this._toolStrip = toolStrip;
            this._location = location;
            this.Collapsed = false;
            this._headerGroup.ButtonSpecs[0].Click += delegate { this.Toggle(); };
            this._toolStrip.Visible = false;
        }

        public bool Visible
        {
            get
            {
                return this._headerInvoker.RunAndReturnInControlsThread(
                    delegate
                        {
                            return this._splitContainer.Panel1.Contains(this._headerGroup)
                                       ? this._splitContainer.Panel1Collapsed == false
                                       : this._splitContainer.Panel2Collapsed == false;
                        });
            }
            set
            {
                this._headerInvoker.RunInControlsThread(
                    delegate
                        {
                            if (this._splitContainer.Panel1.Contains(this._headerGroup))
                            {
                                this._splitContainer.Panel1Collapsed = value == false;
                            }
                            else
                            {
                                this._splitContainer.Panel2Collapsed = value == false;
                            }
                        });
            }
        }

        public bool Collapsed
        {
            get
            {
                return this._headerInvoker.RunAndReturnInControlsThread(
                    delegate { return this._headerGroup.Collapsed; });
            }
            set
            {
                this._headerInvoker.RunInControlsThread(
                    delegate
                        {
                            this._headerGroup.HeaderPositionPrimary = GetOrientation(value);
                            this._splitContainer.SplitterDistance = GetSplitterDistance(value);
                            this._splitContainer.SplitterWidth = GetSpliterWidth(value);
                            this._headerGroup.ButtonSpecs[0].Type = GetArrow(value);
                            this._headerGroup.ButtonSpecs[0].Edge = GetEdge(value);
                            this._headerGroup.Collapsed = value;
                        });
            }
        }

        public string Text
        {
            get
            {
                return this._headerInvoker.RunAndReturnInControlsThread(
                    () => this._headerGroup.ValuesPrimary.Heading);
            }
            set
            {
                this._headerInvoker.RunInControlsThread(
                    () => this._headerGroup.ValuesPrimary.Heading = value);
            }
        }

        public void Toggle()
        {
            if (this.Collapsed == false)
            {
                this._width = this._headerGroup.Width;
            }

            this.Collapsed = !this.Collapsed;
        }

        private PaletteButtonSpecStyle GetArrow(bool collapsed)
        {
            return this._location == SideBars.Left
                ? (collapsed ? PaletteButtonSpecStyle.ArrowRight : PaletteButtonSpecStyle.ArrowLeft)
                : (collapsed ? PaletteButtonSpecStyle.ArrowLeft : PaletteButtonSpecStyle.ArrowRight);
        }

        private int GetSplitterDistance(bool collapsed)
        {
            return this._location == SideBars.Left
                       ? (collapsed ? 26 : this._width)
                       : (collapsed ? this._splitContainer.Width - 26 : this._splitContainer.Width - this._width);
        }

        private PaletteRelativeEdgeAlign GetEdge(bool collapsed)
        {
            return this._location == SideBars.Left 
                ? (collapsed ? PaletteRelativeEdgeAlign.Near : PaletteRelativeEdgeAlign.Far)
                : (collapsed ? PaletteRelativeEdgeAlign.Near : PaletteRelativeEdgeAlign.Near);
        }

        private int GetSpliterWidth(bool collapsed)
        {
            return collapsed ? 0 : 5;
        }

        private VisualOrientation GetOrientation(bool collapsed)
        {
            return collapsed ? VisualOrientation.Right : VisualOrientation.Top;
        }

        public void SetContent(Control control)
        {
            this._headerInvoker.RunInControlsThread(
                delegate
                    {
                        control.Dock = DockStyle.Fill;
                        this._headerGroup.Panel.Controls.Add(control);
                        control.BringToFront();
                    });
        }

        public IToolStripConfigurationExpression ConfigureToolStrip()
        {
            return new ToolStripConfigurationExpression(ObjectFactory.GetInstance<IMenuState>(), this._toolStrip);
        }
    }
}